var iv_index = 7
var iv_length = 22
var salt_index = iv_index+iv_length+10
var salt_length = 11
var ct_index = salt_index+salt_length+8
var ejUtil = {}

ejUtil.aes_encrypt = function(password,plainText) {

	//Calculate the hmac of the plaintext
	var hmac = ejUtil.generate_hmac(password, plainText);
	
	//Append the hmac to the plaintext itself
	plainText = plainText + " " + hmac;
	
	var json = sjcl.encrypt(password,plainText)
	var iv = json.substring(iv_index,iv_index+iv_length)
	var salt = json.substring(salt_index,salt_index+salt_length)
	var ct = json.substring(ct_index,json.length-2)
	var cipherText = iv+salt+ct
	
	return "0"+cipherText
}

ejUtil.aes_decrypt = function (password,cipherText) {
	var iv = cipherText.substring(0,iv_length)
	var salt = cipherText.substring(iv_length,iv_length+salt_length)
	var ct = cipherText.substring(iv_length+salt_length)
	var json = "{\"iv\":\""+iv+"\",\"salt\":\""+salt+"\",\"ct\":\""+ct+"\"}"
	
	//var original_PlainTextWithHMAC = plaintext;
	
	var plainText = "";
	
	try{
		plainText = sjcl.decrypt(password,json)
	}catch(err){
		console.log(err);
	}
	
	return plainText
}

ejUtil.des_encrypt = function (password, plaintext){
	var encrypted = CryptoJS.DES.encrypt(plaintext, password);
	return "1"+encrypted;
}

ejUtil.des_decrypt = function (password, ciphertext){
	var decrypted = CryptoJS.DES.decrypt(ciphertext, password);
	decrypted = ejUtil.hex2a(""+decrypted);
	return decrypted;
}

ejUtil.trides_encrypt = function(password, plaintext){
	var encrypted = CryptoJS.TripleDES.encrypt(plaintext, password);
	return "2"+encrypted;
}

ejUtil.trides_decrypt = function(password, ciphertext){
	var decrypted = CryptoJS.TripleDES.decrypt(ciphertext, password);
	console.log("decrypted hex: "+decrypted);
	decrypted = ejUtil.hex2a(""+decrypted);
	console.log("decrypted text: "+decrypted);
	return decrypted;
}

ejUtil.rabbit_encrypt = function(password, plaintext){
	var encrypted = CryptoJS.Rabbit.encrypt(plaintext, password);
	console.log("rabbit encrypted: "+encrypted);
	return "3"+encrypted;
}

ejUtil.rabbit_decrypt = function(password, ciphertext){
	var decrypted = CryptoJS.Rabbit.decrypt(ciphertext, password);
	decrypted = ejUtil.hex2a(""+decrypted);
	return decrypted;
}

ejUtil.rc4_encrypt = function(password, plaintext){
	var encrypted = CryptoJS.RC4.encrypt(plaintext, password);
	console.log("rc4 encrypted: "+encrypted);
	return "4"+encrypted;
}

ejUtil.rc4_decrypt = function(password, ciphertext){
	var decrypted = CryptoJS.RC4.decrypt(ciphertext, password);
	decrypted = ejUtil.hex2a(""+decrypted);
	return decrypted;
}

ejUtil.hex2a = function(hex){
	var str = '';
    for (var i = 0; i < hex.length; i += 2)
        str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));
    return str;
}

/**
 * Returns an HMAC value using SHA256
 *
 * Given (key, message) this function returns an HMAC using formula:
 *  HMAC = SHA256( key^opad || SHA256(key^ipad || message) )
 *
 * where ipad and opad are constant values 0x36 * 64 and 0x5c * 64.
 *
 * @returns HMAC value of a (key, message) pair
 *
 * @note This code was made referencing two sources:
 *  http://en.wikipedia.org/wiki/HMAC#Implementation
 *  p143 Stinson
 *
 *
 *  
 */
ejUtil.generate_hmac = function(key, message){

	//For sha256 blocksize is 512 bits (so 64 bytes)
	var blocksize = 64;
	
	//Then to find our opad and ipad values
	var opad = 0x5c * blocksize;
	var ipad = 0x36 * blocksize;
	
	//Hash the key to be safe on length and to convert to number
	key = sjcl.hash.sha256.hash(key);
	
	//Get key1 and key2
	var key1 = opad ^ key; // operator ^ is bitwise XOR; supposidly numbers do not have to be in binary already?
	var key2 = ipad ^ key;

	var hmac = sjcl.hash.sha256.hash( key1 + sjcl.hash.sha256.hash((key2 + message)) ) ;
	
	return hmac;
}
    